<template>

    <NForm
        ref="formRef"
        :rules="formRule"
        :model="formData"
        :size="'large'"
        label-width="auto"
        label-placement="left"
        require-mark-placement="right-hanging">

        <NFormItem label="上级节点" path="parent">
            <NTreeSelect
                v-model:value="formData.parent"
                :options="[{key: '0',label: '顶级', children: treeData}]"
                :default-expanded-keys="['0']"
                :node-props="()=> ({'style': '--n-node-content-height: 32px;'})"
                placeholder="请选择所属上级" />
        </NFormItem>

        <NFormItem label="类型" path="type">
            <NSelect v-model:value="formData.type" placeholder="状态" :options="RouteTypeOption" />
        </NFormItem>

        <NFormItem label="名称" path="name">
            <NInput v-model:value="formData.name" placeholder="请输入名称" clearable :allow-input="(value) => !value.includes(' ')" />
        </NFormItem>

        <template v-if="formData.type == '2' || formData.type == '3'">
            <NFormItem label="权限标识" path="authority">
                <NInput v-model:value="formData.authority" placeholder="请输入权限标识" clearable :allow-input="(value) => !value.includes(' ')" />
            </NFormItem>
        </template>

        <template v-if="formData.type == '2'">
            <NFormItem label="路由地址" path="path">
                <NInput v-model:value="formData.path" placeholder="请输入路由地址" clearable :allow-input="(value) => !value.includes(' ')" />
            </NFormItem>
            <NFormItem label="路由组件" path="component">
                <NInput v-model:value="formData.component" placeholder="请输入路由组件" clearable :allow-input="(value) => !value.includes(' ')" />
            </NFormItem>
        </template>

        <NFormItem label="数据排序" path="sort">
            <NInputNumber :min="0" :max="9999" v-model:value="formData.sort" placeholder="请输入数据排序" class="w-full" />
        </NFormItem>

        <template v-if="formData.type == '2'">
            <NFormItem label="显示状态" path="visible">
                <n-select v-model:value="formData.visible" placeholder="状态" :options="VisibleOption" />
            </NFormItem>
        </template>

        <n-form-item label="是否启用" path="status">
            <n-select v-model:value="formData.status" placeholder="状态" :options="StatusOption" />
        </n-form-item>

        <n-divider />

        <n-space justify="end" size="large">
            <n-button @click="cancel">取消</n-button>
            <n-button @click="confirm" type="primary">确认</n-button>
        </n-space>

    </NForm>

</template>

<script setup lang="ts">
import {Api} from '@/api/type'
import {onMounted, ref, watch} from 'vue'
import {BaseApi} from '@/api/base-api'
import {StatusOption, VisibleOption} from '@/type/common'
import {RouteTypeOption} from '@/type/system'
import {TreeSelectOption} from 'naive-ui/es/tree-select/src/interface'
import {FormInst, FormRules, NButton, NDivider, NForm, NFormItem, NInput, NInputNumber, NSelect, NSpace, NTreeSelect, useMessage} from 'naive-ui'
// -------------------------------------------------
type R<T> = Api.Common.R<T>;
type Data = Api.System.Route;
// -------------------------------------------------
const emit = defineEmits(['confirm', 'cancel'])

const {identity, parent} = defineProps({
    identity: {
        type: String,
        default: ''
    },
    parent: {
        type: String,
        default: '0'
    }
})

const message = useMessage()
const baseApi = new BaseApi<Data>('route')
const loading = ref<boolean>(false)
const parentData = ref<Partial<Data>>({})
const formData = ref<Data>({
    identity: '',
    parent: '0',
    name: '',
    icon: '',
    authority: '',
    path: '',
    component: '',
    type: 1,
    sort: 1,
    visible: 1,
    status: 1
})
const treeData = ref<Array<TreeSelectOption>>([])
const formRef = ref<FormInst | null>(null)
const formRule: FormRules = {
    parent: [
        {
            required: true,
            trigger: ['change', 'blur'],
            validator() {
                if (!formData.value?.parent) {
                    return new Error('请选择所属上级')
                }
                return true
            }
        }
    ],
    name: [
        {
            required: true,
            message: '请填写数据名称',
            trigger: ['input', 'blur']
        },
        {
            min: 2,
            max: 50,
            message: '数据名称长度只能在2到50个字符之间',
            trigger: ['input', 'blur']
        }
    ],
    type: [
        {
            type: 'number',
            required: true,
            message: '请选择数据类型',
            trigger: ['change', 'blur']
        }
    ],
    visible: [
        {
            type: 'number',
            required: true,
            message: '请选择显示状态',
            trigger: ['change', 'blur']
        }
    ],
    status: [
        {
            type: 'number',
            required: true,
            message: '请选择数据状态',
            trigger: ['change', 'blur']
        }
    ]
}

watch(() => formData.value.type, (type) => {
    console.info(type)
    if (type == '1') {
        formData.value.path = ''
        formData.value.component = ''
        formData.value.status = 1
        formData.value.visible = 1
        formData.value.authority = ''
    }
    if (type == '2') {
        formData.value.status = 1
        formData.value.visible = 1
    }
    if (type == '3') {
        formData.value.path = ''
        formData.value.component = ''
        formData.value.status = 1
        formData.value.visible = 1
    }
})

async function confirm() {
    if (formData.value.identity) {
        await modifyData()
    } else {
        await additionData()
    }
    emit('confirm')
}

async function cancel() {
    emit('cancel')
}

async function additionData() {
    await formRef.value?.validate()
    loading.value = true
    await baseApi.additionData(formData.value)
    loading.value = false
}

async function modifyData() {
    await formRef.value?.validate()
    loading.value = true
    await baseApi.modifyData(formData.value)
    loading.value = false
}

/**
 * 组装用户路由树
 */
const generateTree = (list: Array<Data>): Array<TreeSelectOption> => {
    let map: Map<string, TreeSelectOption> = list.reduce((data: Map<string, TreeSelectOption>, item: Data) => {
        if (item.type == '1' || item.type == '2') {
            data.set(item.identity, {
                key: item.identity,
                parent: item.parent,
                label: item.name
            })
        }
        return data
    }, new Map<string, TreeSelectOption>())

    map.forEach((value, key) => {
        let parent = map.get(value['parent'] as string)
        if (parent) {
            if (!parent?.children) {
                parent.children = []
            }
            parent.children.push(value)
        }
    })
    return list.filter((item: Data): boolean => item.parent == '0').map(item => map.get(item.identity)!)
}

async function getDataInfo(identity: string): Promise<Data | null> {
    loading.value = true
    let result: R<Data> = await baseApi.getDataInfo({identity: identity})
    loading.value = false
    if (result.code == 0) {
        return result.data
    } else {
        console.error(message)
        message.error(result.message)
        return null
    }
}

async function getDataList(): Promise<Array<Data>> {
    loading.value = true
    let result: R<Array<Data>> = await baseApi.getDataList({})
    loading.value = false
    if (result.code == 0) {
        return result.data
    } else {
        console.error(message)
        message.error(result.message)
        return []
    }
}

function treeNodeProp() {
    return {
        style: '--n-node-content-height: 34px;'
    }
}

async function initialize() {
    let _parent = parent
    let _identity = identity
    if (_identity) {
        let data = await getDataInfo(_identity)
        if (data) {
            formData.value = data
            _parent = data.parent
        } else {
            console.error('查询数据失败')
            message.error('查询数据失败')
        }
    }
    if (_parent && _parent != '0') {
        let data = await getDataInfo(_parent)
        if (data) {
            parentData.value = data
            formData.value.parent = data.identity
        } else {
            parentData.value = {}
            console.error('查询部门数据失败')
            message.error('查询部门数据失败')
        }
    }

    let routeList = await getDataList()
    treeData.value = generateTree(routeList)
}

onMounted(() => {
    initialize()
})
</script>
